Container: Don’t scroll to unset focus child coord
authorDaniel Boles <dboles@src.gnome.org>
Mon, 7 Aug 2017 17:32:57 +0000 (18:32 +0100)
committerDaniel Boles <dboles@src.gnome.org>
Mon, 7 Aug 2017 18:21:09 +0000 (19:21 +0100)
In gtk_container_real_set_focus_child(), we try to scroll to the
position of the new :focus-child if we have h or v adjustments.

gtk_widget_translate_coordinates() returns FALSE if neither widget is
realized or in other situations that cause output parameters x and y not
to be set. Thus, if the caller did not initialise x/y and uses them even
if the function returned FALSE, they are using uninitialised variables.

In gtk_container_real_set_focus_child(), we did not check the return
value but merrily went ahead and used x and y regardless. This is UB, as
revealed by Valgrind, as well as being pointless.

The trivial fix is to exit early if (!gtk_widget_translate_coordinates).

https://bugzilla.gnome.org/show_bug.cgi?id=776909

gtk/gtkcontainer.c

index bc52c9955451a0c5769d91284968e99b48c89c71..b24bef843d92e5dfbc39ebd3d9892e08fde7c668 100644 (file)
@@ -2038,8 +2038,7 @@ gtk_container_real_set_focus_child (GtkContainer *container,
   g_return_if_fail (GTK_IS_CONTAINER (container));
   g_return_if_fail (focus_child == NULL || GTK_IS_WIDGET (focus_child));
 
-  /* check for h/v adjustments
-   */
+  /* Check for h/v adjustments and scroll to show the focus child if possible */
   if (focus_child)
     {
       GtkAdjustment *hadj;
@@ -2056,8 +2055,9 @@ gtk_container_real_set_focus_child (GtkContainer *container,
           while (gtk_widget_get_focus_child (child))
             child = gtk_widget_get_focus_child (child);
 
-          gtk_widget_translate_coordinates (child, focus_child,
-                                            0, 0, &x, &y);
+          if (!gtk_widget_translate_coordinates (child, focus_child,
+                                                 0, 0, &x, &y))
+            return;
 
           _gtk_widget_get_allocation (focus_child, &allocation);
           x += allocation.x;